//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2013 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef _BUOLA_AUTO_EXCEPTIONS_H_
#define _BUOLA_AUTO_EXCEPTIONS_H_

#include <stdexcept>
#include <string>

namespace buola {

/// \addtogroup exceptions
///@{

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// hardware error
///
/// Hardware errors represent problems with unavailable or malfunctioning
/// hardware.
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XHardware : public std::runtime_error
{
public:
    explicit XHardware(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XHardware()
        :   std::runtime_error("Hardware failure") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// permission error
///
/// Permission errors occur when the program tries to access some resource
/// it is not allowed to, such as trying to create a file in a folder
/// where the user doesn't have write access.
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XPermission : public std::runtime_error
{
public:
    explicit XPermission(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XPermission()
        :   std::runtime_error("Insufficient permissions") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// collision error
///
/// Collision errors occur when the program tries to access a resource which
/// is temporarily unavailable because another user or program is accessing
/// it at the same time
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XCollision : public std::runtime_error
{
public:
    explicit XCollision(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XCollision()
        :   std::runtime_error("Collision accessing shared resource") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// connection error
///
/// Connection errors occur when the other side of a communication channel is
/// not responding or gets disconnected, such as in a broken pipe.
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XConnection : public std::runtime_error
{
public:
    explicit XConnection(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XConnection()
        :   std::runtime_error("There's no one there") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// already-exists error
///
/// This kind of error occurs when trying to create an object which already exists.
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XAlready : public std::runtime_error
{
public:
    explicit XAlready(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XAlready()
        :   std::runtime_error("It already exists") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// not-found error
///
/// This kind of error occurs when trying to access an object which doesn't exist
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XNotFound : public std::runtime_error
{
public:
    explicit XNotFound(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XNotFound()
        :   std::runtime_error("It doesn't exist") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// not-enough error
///
/// It occurs when not enough data is available to fulfill a request
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XNotEnough : public std::runtime_error
{
public:
    explicit XNotEnough(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XNotEnough()
        :   std::runtime_error("Not enough data available") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// device-full error
///
/// It occurs when there is not enough space on a device to complete some disk
/// operation
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XFull : public std::runtime_error
{
public:
    explicit XFull(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XFull()
        :   std::runtime_error("Not enough room") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// out-of-memory error
///
/// This error occurs when there is not enough memory available to complete
/// some memory management operation
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XMemory : public std::runtime_error
{
public:
    explicit XMemory(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XMemory()
        :   std::runtime_error("Out of memory") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// input/output error
///
/// This exception should be thrown when an I/O error makes it impossible to complete some operation
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XIO : public std::runtime_error
{
public:
    explicit XIO(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XIO()
        :   std::runtime_error("IO error") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// data error
///
/// This exception should be thrown when some data being processed doesn't have the right format
/// or is invalid in some other way
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XData : public std::runtime_error
{
public:
    explicit XData(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XData()
        :   std::runtime_error("IO error") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// internal error
///
/// It occurs when there is some internal problem in the library, and the
/// nature of the problem is unknown.
///
/// This is mostly used to report unknown errors in other libraries that buola uses.
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XInternal : public std::runtime_error
{
public:
    explicit XInternal(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XInternal()
        :   std::runtime_error("Internal library error") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// option-parsing error
///
/// This error occurs when some of the parameters provided at the command line
/// don't have the right arguments
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XOptionParsing : public std::runtime_error
{
public:
    explicit XOptionParsing(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// not-implemented error
///
/// This exception should be thrown when a function is not yet implemented.
///
/// Inherits from \c std::logic_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XNotImplemented : public std::logic_error
{
public:
    explicit XNotImplemented(const std::string &pFunction)
        :   std::logic_error("Function not implemented: "+pFunction) 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// argument error
///
/// This exception is thrown when an argument to some function is not valid
///
/// Inherits from \c std::invalid_argument
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XArgument : public std::invalid_argument
{
public:
    explicit XArgument(const std::string &pText)
        :   std::invalid_argument(pText) 
    {}
    
    XArgument()
        :   std::invalid_argument("Wrong argument to function") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// mismatch error
///
/// This exception is thrown when there is a mismatch between arguments to some function
///
/// Inherits from \c std::invalid_argument
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XMismatch : public std::invalid_argument
{
public:
    explicit XMismatch(const std::string &pText)
        :   std::invalid_argument(pText) 
    {}
    
    XMismatch()
        :   std::invalid_argument("Wrong argument to function") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// range error
///
/// This exception is thrown when an argument to some function is out of range
///
/// Inherits from \c std::out_of_range
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XRange : public std::out_of_range
{
public:
    explicit XRange(const std::string &pText)
        :   std::out_of_range(pText) 
    {}
    
    XRange()
        :   std::out_of_range("Argument is out of range") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// invalid-object error
///
/// This exception is thrown when a function is called on an object which is in an invalid state
/// or on an object which doesn't support an operation
///
/// Inherits from \c std::logic_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XInvalid : public std::logic_error
{
public:
    explicit XInvalid(const std::string &pText)
        :   std::logic_error(pText) 
    {}
    
    XInvalid()
        :   std::logic_error("Object is in an invalid state") 
    {}
};

/////////////////////////////////////////////////////////////////////////////////////////////////
///
/// process error
///
/// This exception is thrown when the processing of some data fails, probably because of an input error
/// or because the code is wrong
///
/// Inherits from \c std::runtime_error
///
/////////////////////////////////////////////////////////////////////////////////////////////////

class XProcess : public std::runtime_error
{
public:
    explicit XProcess(const std::string &pText)
        :   std::runtime_error(pText) 
    {}
    
    XProcess()
        :   std::runtime_error("Process error") 
    {}
};

///@}

/*namespace buola*/ }

#endif
